package com.chen.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.chen.domain.SysMenu;
import com.chen.domain.SysRole;
import com.chen.feign.OAuth2FeignClient;
import com.chen.model.JwtToken;
import com.chen.model.UserLoginModel;
import com.chen.service.SysMenuService;
import com.chen.service.SysRoleService;
import com.chen.service.SysUserLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: chen
 * @Date: 2021/4/19 10:39 AM
 * @Version 1.0
 */
@Service
@Slf4j
public class SysUserLoginServiceImpl implements SysUserLoginService {

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysRoleService sysRoleService;

    @Resource
    private OAuth2FeignClient oAuth2FeignClient;

    @Value("${user.basicToken:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken;

    @Override
    public UserLoginModel login(String username, String password) {

        UserLoginModel userLoginModel = new UserLoginModel();

        //1.参数校验
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            throw new RuntimeException("用户名或密码为空");
        }
        //2.开始登录  --> 远程调用授权服务器  -->  解析调用接口 ---> token
        log.info("远程调用授权服务器开始");
        ResponseEntity<JwtToken> login = oAuth2FeignClient.getToken(username, password, "password",
                "admin_type", basicToken);
        if (login.getStatusCode() != HttpStatus.OK) {
            throw new ApiException("用户名或密码错误");
        }
        JwtToken body = login.getBody();
        assert body != null;
        userLoginModel.setToken(body.getTokenType() + " " + body.getAccessToken());
        //3.查询登录成功的用户的菜单数据

        Jwt decode = JwtHelper.decode(body.getAccessToken());
        String claims = decode.getClaims();
        JSONObject jsonObject = JSON.parseObject(claims);

        //todo  现在查所有
        String id = (String) jsonObject.get("user_name");

        List<SysMenu> menus = new ArrayList<>();
        boolean flag = false;
        //查询角色
        List<SysRole> sysRoles = sysRoleService.findUserRole(id);
        for (SysRole sysRole : sysRoles) {
            if (sysRole.getCode().equalsIgnoreCase("ROLE_ADMIN")) {
                menus = sysMenuService.list();
                flag = true;
                break;
            }
        }
        if (!flag) {
            menus = sysMenuService.findUserRoleMenu(id);
        }

        userLoginModel.setMenus(menus);

        //4.查询登录成功的用户的权限数据
        JSONArray authorities = jsonObject.getJSONArray("authorities");
        List<SimpleGrantedAuthority> collect = authorities.stream() // 组装我们的权限数据
                .map(authorityJson -> new SimpleGrantedAuthority(authorityJson.toString()))
                .collect(Collectors.toList());
        userLoginModel.setAuthorities(collect);

        //5.缓存jwt -token   - ---- >  redis
        //todo 存储redis

        return userLoginModel;
    }
}
